home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / MLOCAL.ARJ / MLTEST.C < prev    next >
C/C++ Source or Header  |  1991-03-16  |  27KB  |  973 lines

  1. /*----------------------------------------------------------------------------
  2.  MLHTEST.C
  3.  Multiple Local Heap Demo
  4.  10-3-90
  5.  danq
  6. ----------------------------------------------------------------------------*/
  7.  
  8. #include <windows.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include "mlocal.h"
  12. #include "listmgr.h"
  13. #include "mltest.h"
  14.  
  15. // Window class names
  16. static char szFrame[] = "MDIframe";
  17. static char szChild[] = "MDIchild";
  18.  
  19. // Output strings
  20. static char szPrint[] = "  %04u    %04X    %05u          %02X   %s";
  21. static char szSum[]   = "Size: %05u  Used: %05u  Free: %05u";
  22. static char szBar[]   = "-------------------------------------------------";
  23. static char szBlank[] = "                                                 ";
  24. static char szTitle[] = "Handle  Offset   Length  Lock Count   Flags      ";
  25.  
  26. // Global Variables
  27. extern      WORD _B000h;
  28. HANDLE      hInst;
  29. HANDLE      hAccel;
  30. HWND        hwndFrame;
  31. HWND        hwndMDIClient;
  32. HWND        hwndActive;
  33. WORD        wActiveMenu;
  34. WORD        wSelectedColor;
  35. WORD        wLastCheck;
  36. WORD        wLFlags;
  37. INT         xChar,yChar;
  38. DWORD       na;
  39. HLIST       hList;
  40.  
  41.  
  42. typedef struct tStruct {
  43.     int    a;
  44.     int    b;
  45.     char   c;
  46. } TSTRUCT, FAR * LPTSTRUCT;
  47.  
  48. /*----------------------------------------------------------------------------
  49.     MonoAtSay(INT,INT, LPSTR) : VOID
  50.     Outputs a string directly to the monochrome video hardware
  51. ----------------------------------------------------------------------------*/
  52. VOID MonoAtSay(INT x, INT y, LPSTR tmp)
  53. {
  54.  
  55.     LPSTR scr = (LPSTR) MAKELONG((((y * 80) + x) * 2),&_B000h);
  56.     
  57.     _asm {
  58.         push    ds
  59.         push    di
  60.         push    si
  61.  
  62.         les     di,scr
  63.         lds     si,tmp
  64.         mov     ah,0x70
  65.  
  66. MOloop: lodsb
  67.         cmp     al,0
  68.         je      MOdone
  69.         stosw
  70.         jmp short MOloop
  71.  
  72. MOdone: pop     si
  73.         pop     di
  74.         pop     ds
  75.     }
  76. }
  77.  
  78. /*----------------------------------------------------------------------------
  79.     InitializeApplication(void) : BOOL
  80.     Registers window classes.
  81. ----------------------------------------------------------------------------*/
  82. BOOL InitializeApplication()
  83. {
  84.     WNDCLASS    WndClass;
  85.  
  86.     memset(&WndClass, 0, sizeof(WndClass));
  87.  
  88.     //Prepare MDIFrame class structure
  89.     WndClass.style          = 0;
  90.     WndClass.lpfnWndProc    = MDIFrameWndProc;
  91.     WndClass.hInstance      = hInst;
  92.     WndClass.hIcon          = LoadIcon(hInst, MAINICON);
  93.     WndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  94.     WndClass.hbrBackground  = COLOR_APPWORKSPACE;
  95.     WndClass.lpszMenuName   = AppMenu;
  96.     WndClass.lpszClassName  = szFrame;
  97.  
  98.     //Register MDIframe class
  99.     if (!RegisterClass(&WndClass))
  100.         return FALSE;
  101.  
  102.     //Prepare MDIChild class structure
  103.     WndClass.lpfnWndProc    = MDIChildWndProc;
  104.     WndClass.hIcon          = LoadIcon(hInst, CHILDICON);
  105.     WndClass.lpszMenuName   = NULL;
  106.     WndClass.lpszClassName  = szChild;
  107.     WndClass.cbWndExtra     = WE_EXTRA;
  108.  
  109.     // Register MDIChild class
  110.     if (!RegisterClass(&WndClass))
  111.         return FALSE;
  112.  
  113.     return TRUE;
  114. }
  115.  
  116. /*----------------------------------------------------------------------------
  117.     InitializeInstance(WORD) : BOOL
  118.     Called for every instance of MLHTest.
  119. ----------------------------------------------------------------------------*/
  120. BOOL InitializeInstance(WORD nCmdShow)
  121. {
  122.     char   sz[80];
  123.     HDC    hdc;
  124.     HMENU  hmenu;
  125.     CLIENTCREATESTRUCT ccs;
  126.  
  127.     LoadString(hInst, IDS_APPNAME, sz, sizeof(sz));
  128.     hwndFrame = CreateWindow (szFrame,
  129.         sz,
  130.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  131.         CW_USEDEFAULT,0,
  132.         CW_USEDEFAULT,0,
  133.         NULL,
  134.         NULL,
  135.         hInst,
  136.         NULL);
  137.  
  138.     if (!hwndFrame)
  139.         return FALSE;
  140.  
  141.     ccs.hWindowMenu  = GetSubMenu(GetMenu(hwndFrame), WINDOWMENU);
  142.     ccs.idFirstChild = IDM_WINDOWCHILD;
  143.  
  144.     hwndMDIClient = CreateWindow ("MDIclient",
  145.         NULL,
  146.         WS_CHILD|WS_CLIPCHILDREN,
  147.         0,0,
  148.         0,0,
  149.         hwndFrame,
  150.         0x100,
  151.         hInst,
  152.         (LPSTR)&ccs);
  153.  
  154.     if (!hwndMDIClient)
  155.         return FALSE;
  156.  
  157.     if (!(hAccel = LoadAccelerators(hInst, IDMLHTest)))
  158.         return FALSE;
  159.  
  160.     ShowWindow(hwndFrame,nCmdShow);
  161.  
  162.     UpdateWindow(hwndFrame);
  163.     ShowWindow(hwndMDIClient, nCmdShow);
  164.     UpdateWindow(hwndMDIClient);
  165.     wActiveMenu = WINDOWMENU;
  166.     na = 1;
  167.     return TRUE;
  168. }
  169.  
  170.  
  171. /*----------------------------------------------------------------------------
  172.   WinMain( HANDLE, HANDLE, LPSTR, int ) : int
  173.   Calls the initialization routines and contains the message loop.
  174. ----------------------------------------------------------------------------*/
  175. INT PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInst,LPSTR lpCmdLine, INT nCmdShow)
  176. {
  177.     MSG         msg;
  178.  
  179.     hInst = hInstance;
  180.  
  181.     // Initialize things needed for this application
  182.     if (!hPrevInst) {
  183.         if (!InitializeApplication())
  184.             return 0;
  185.     }
  186.  
  187.     // Create the frame and do other initialization
  188.     if (!InitializeInstance(nCmdShow))
  189.         return 0;
  190.  
  191.  
  192.     // Process messages
  193.     while (GetMessage(&msg, NULL, 0, 0)) {
  194.         if (!TranslateMDISysAccel(hwndMDIClient, &msg) &&
  195.               !TranslateAccelerator(hwndFrame, hAccel, &msg)) {
  196.             TranslateMessage(&msg);
  197.             DispatchMessage(&msg);
  198.         }
  199.     }
  200.     return msg.wParam;
  201. }
  202.  
  203. /*----------------------------------------------------------------------------
  204.   RepaintChild(VOID) : VOID
  205.   Sends a WM_PAINT to the active MDI Child
  206. ----------------------------------------------------------------------------*/
  207. VOID RePaintChild(VOID)
  208. {
  209.     InvalidateRect(hwndActive, (LPRECT) NULL, TRUE);
  210. }
  211.  
  212. /*----------------------------------------------------------------------------
  213.   RepaintChild(VOID) : VOID
  214.   Sends a WM_PAINT to the active MDI Child
  215. ----------------------------------------------------------------------------*/
  216.  
  217. /*----------------------------------------------------------------------------
  218.   LockArena(VOID) : LPLOCALARENA
  219.   Locks the Active MDIChilds arena
  220. ----------------------------------------------------------------------------*/
  221. LPLOCALARENA LockArena(VOID)
  222. {
  223.     return ((LPLOCALARENA)MultLocalLock(ActiveHeap, ActiveArena));
  224. }
  225.  
  226. /*----------------------------------------------------------------------------
  227.   UnlockArena(VOID) : VOID
  228.   Unlocks the Active MDIChilds arena
  229. ----------------------------------------------------------------------------*/
  230. VOID UnlockArena(VOID)
  231. {
  232.     MultLocalUnlock(ActiveHeap, ActiveArena);
  233. }
  234.  
  235. /*----------------------------------------------------------------------------
  236.   ChangeMDIMenu(VOID) : VOID
  237.   Changes the frame Menu based on what state the active MDI child is in.
  238. ----------------------------------------------------------------------------*/
  239. VOID ChangeMDIMenu(VOID)
  240. {
  241.     HMENU hMenu;
  242.     HMENU hWindowMenu;
  243.     int i;
  244.  
  245.     i = (((hwndActive) && (!IsIconic(hwndActive))) ? WINDOWMENUCHILD : WINDOWMENU);
  246.     if (wActiveMenu != i) {
  247.         wActiveMenu = i;
  248.         if (i == WINDOWMENUCHILD)
  249.             hMenu = LoadMenu (hInst, ChildMenu);
  250.         else
  251.             hMenu = LoadMenu (hInst, AppMenu);
  252.         hWindowMenu = GetSubMenu (hMenu, i);
  253.         hMenu = (HMENU) SendMessage (hwndMDIClient, WM_MDISETMENU, 0, MAKELONG(hMenu,hWindowMenu));
  254.         DestroyMenu (hMenu);
  255.         DrawMenuBar (hwndFrame);
  256.     }
  257. }
  258.  
  259. /*----------------------------------------------------------------------------
  260.   AboutDialog(HWND) : VOID
  261.   Displays the About Dialog
  262. ----------------------------------------------------------------------------*/
  263. VOID AboutDialog(HWND hwnd)
  264. {
  265.     FARPROC lpProc;
  266.     lpProc = MakeProcInstance( MainDlgAbout, hInst );
  267.     DialogBox( hInst, "MainAbout", hwnd, lpProc );
  268.     FreeProcInstance( lpProc );
  269. }
  270.  
  271. /*----------------------------------------------------------------------------
  272.   AvoidArenaHandle(HANDLE) : BOOL
  273.   Returns FALSE if passed handle is the local arena
  274. ----------------------------------------------------------------------------*/
  275. BOOL AvoidArenaHandle(HANDLE h)
  276. {
  277.     if (h == ActiveArena) {
  278.         MessageBox(hwndFrame,"Cannot Access Arena Handle", "Error", MB_ICONEXCLAMATION);
  279.         return (FALSE);
  280.     }
  281.     else
  282.         return (TRUE);
  283. }
  284.  
  285. /*----------------------------------------------------------------------------
  286.   GetSize(LPSTR) : WORD
  287.   Displays the appropriate size dialog and returns user input value
  288. ----------------------------------------------------------------------------*/
  289. WORD GetSize (LPSTR dlg)
  290. {
  291.     WORD    i;
  292.     FARPROC lpProc;
  293.     lpProc = MakeProcInstance(NewHeapDlgProc, hInst);
  294.     i = DialogBox(hInst, dlg, hwndFrame, lpProc);
  295.     FreeProcInstance(lpProc);
  296.     return(i);
  297. }
  298.  
  299. /*----------------------------------------------------------------------------
  300.   GetAllocSize(VOID) : WORD
  301.   Displays the Alloc size dialog and returns user input values
  302.   Allocation Flags are returned in wLFlags global variable
  303. ----------------------------------------------------------------------------*/
  304. WORD GetAllocSize (VOID)
  305. {
  306.     WORD    i;
  307.     FARPROC lpProc;
  308.     lpProc = MakeProcInstance(AllocDlgProc, hInst);
  309.     i = DialogBox(hInst, "Alloc", hwndFrame, lpProc);
  310.     FreeProcInstance(lpProc);
  311.     return(i);
  312. }
  313.  
  314. /*----------------------------------------------------------------------------
  315.   GetSize(VOID) : HANDLE
  316.   Displays the Handle dialog and returns user input value
  317. ----------------------------------------------------------------------------*/
  318. HANDLE GetHandle (VOID)
  319. {
  320.     HANDLE i;
  321.     FARPROC lpProc;
  322.     lpProc = MakeProcInstance( HandleDlgProc, hInst );
  323.     i = DialogBox( hInst, "Memory", hwndActive, lpProc );
  324.     FreeProcInstance( lpProc );
  325.     if (!AvoidArenaHandle(i))
  326.         return FALSE;
  327.     else
  328.         return i;
  329. }
  330.  
  331.  
  332.  
  333. /*----------------------------------------------------------------------------
  334.   GetHandleAndSize(VOID) : WORD
  335.   Displays the ReAlloc dialog and returns user input values
  336.   Handle is returned in wLFlags global
  337. ----------------------------------------------------------------------------*/
  338. WORD GetHandleAndSize ( VOID)
  339. {
  340.     WORD i;
  341.     FARPROC lpProc;
  342.     lpProc = MakeProcInstance( ReAllocDlgProc, hInst );
  343.     i = DialogBox( hInst, "ReAlloc", hwndActive, lpProc );
  344.     FreeProcInstance(lpProc);
  345.     if (!AvoidArenaHandle(wLFlags))
  346.         return FALSE;
  347.     else
  348.         return i;
  349. }
  350.  
  351. /*----------------------------------------------------------------------------
  352.   MyListCompare() : WORD
  353.   Comparison Routine for ListSort
  354.  
  355.   Returns : LESSTHAN
  356.             EQUAL
  357.             GREATERTHAN
  358.  
  359. ----------------------------------------------------------------------------*/
  360. WORD FAR PASCAL MyListCompare(LPTSTRUCT lpComp1,LPTSTRUCT lpComp2)
  361. {
  362.     if (lpComp1->c > lpComp2->c)
  363.         return(GREATERTHAN);
  364.     if (lpComp1->c < lpComp2->c)
  365.         return(LESSTHAN);
  366.     if (lpComp1->c = lpComp2->c)
  367.         return(EQUAL);
  368. }
  369.  
  370. /*----------------------------------------------------------------------------
  371.   MDIFrameWndProc( hwndMain, message, wParam, lParam ) : LONG;
  372.   Handles messages for the MDI desktop.  This includes any WM_COMMAND
  373.   messages that are received for the MDIchild windows.
  374. ----------------------------------------------------------------------------*/
  375. LONG FAR PASCAL MDIFrameWndProc(HWND hwnd, unsigned msg,WORD wParam, LONG lParam)
  376. {
  377.     WORD wSize;
  378.     HANDLE hlMem;
  379.     LPLOCALARENA lpArena;
  380.     INT i;
  381.  
  382.     switch (msg) {
  383.  
  384.         case WM_COMMAND:
  385.  
  386.             switch( wParam ) {
  387.  
  388.                 case IDM_NEW:
  389.                     if (wSize = GetSize("NewHeap"))
  390.                         MLHTestCreate((wSize * 1024));
  391.                     break;
  392.                 case IDM_LISTMGR:
  393.                     {
  394.                         LPTSTRUCT lpTmp,lpTmp1;
  395.                         int i;
  396.                         FARPROC lpCompare;
  397.                         char ch = 'z';
  398.                         char st[11];
  399.                         
  400.                         hList = ListCreate(sizeof(TSTRUCT));
  401.                         for (i=1;i<=26;i++) {
  402.                             lpTmp = ListAllocNode(hList);
  403.                             lpTmp->a = i;
  404.                             lpTmp->b = i * 0x10;
  405.                             lpTmp->c = ch;
  406.                             ch--;
  407.                             ListAddNode(hList, lpTmp);
  408.                         }
  409.                         ListDump(hList);
  410.  
  411.                         lpCompare = MakeProcInstance(MyListCompare, hInst);
  412.                         ListQSort(hList, lpCompare);
  413.                         FreeProcInstance(lpCompare);
  414.  
  415.                         ListDump(hList);
  416.  
  417.                         lpTmp = ListGetFirstNode(hList);
  418.                         i = 0;
  419.                         while (lpTmp) {
  420.                             st[i] = lpTmp->c;
  421.                             i++;
  422.                             lpTmp = ListGetNextNode(hList, lpTmp);
  423.                         }
  424.                         st[i] = 0;
  425.                         MessageBox(hwnd,(LPSTR) st, "Sort Results", MB_ICONSTOP);
  426.  
  427.                         lpTmp  = ListGetNode(hList,5);
  428.                         lpTmp1 = ListGetPrevNode(hList,lpTmp);
  429.                         ListDeleteNode(hList,lpTmp);
  430.  
  431.                         ListDump(hList);
  432.  
  433.                         lpTmp = ListAllocNode(hList);
  434.                         lpTmp->a = 5;
  435.                         lpTmp->b = 5 * 0x10;
  436.                         ListInsertNode(hList, lpTmp1, lpTmp);
  437.  
  438.                         ListDump(hList);
  439.  
  440.                         lpTmp = ListGetFirstNode(hList);
  441.                         while (lpTmp) {
  442.                             i = lpTmp->a + lpTmp->b;
  443.                             lpTmp = ListGetNextNode(hList, lpTmp);
  444.                         }
  445.                         ListFree(hList);
  446.                         
  447.                     }
  448.                     break;
  449.                     
  450.                 case IDM_FARLOCAL:
  451.                     {
  452.                         char szText[80];
  453.                         FHANDLE tmp;
  454.                         if (wSize = GetSize("ShrinkHeap")) {
  455.                             for (i=1;i<10240;i++) {
  456.                                 if(!(tmp = FarLocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, wSize))) {
  457.                                     MessageBox(hwnd, "Failure","FarLocal",MB_ICONSTOP);
  458.                                     break;
  459.  
  460.                                 }
  461.                                 else {
  462.                                     na++;
  463.                                     sprintf(szText, "Heap:Handle %Fp (Allocation :%07lu)",tmp, na);
  464.                                     MonoAtSay(0,0,szText);
  465.                                 }
  466.                             }
  467.                         }
  468.                     }
  469.                     break;
  470.  
  471.                 case IDM_ABOUT:
  472.                     AboutDialog(hwnd);
  473.                     break;
  474.  
  475.                 case IDM_WINDOWTILE:
  476.                     SendMessage(hwndMDIClient, WM_MDITILE, 0, 0L);
  477.                     break;
  478.  
  479.                 case IDM_WINDOWCASCADE:
  480.                     SendMessage(hwndMDIClient, WM_MDICASCADE, 0, 0L);
  481.                     break;
  482.  
  483.                 case IDM_WINDOWICONS:
  484.                     SendMessage(hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  485.                     break;
  486.  
  487.                 case IDM_WINDOWCLOSEALL:
  488.                     CloseAllChildren();
  489.                     ShowWindow(hwndMDIClient, SW_SHOW);
  490.                     break;
  491.  
  492.                 case IDM_MENUCHANGE:
  493.                     ChangeMDIMenu();
  494.                     break;
  495.  
  496.                 case IDM_EXIT:
  497.                     PostMessage(hwndFrame, WM_SYSCOMMAND, SC_CLOSE, 0L);
  498.                     break;
  499.  
  500.                 case IDM_ALLOC:
  501.                     if (lpArena = LockArena()) {
  502.                         for (i=1;i<=ARENALIMIT;i++) {
  503.                             if (lpArena->handle == 0) {
  504.                                 if (wSize = GetAllocSize()) {
  505.                                     lpArena->handle = MultLocalAlloc(ActiveHeap, wLFlags, wSize);
  506.                                     lpArena->wFlags = wLFlags;
  507.                                     RePaintChild();
  508.                                 }
  509.                                 break;
  510.                             }
  511.                             lpArena++;
  512.                         }
  513.                         UnlockArena();
  514.                     }
  515.                     break;
  516.  
  517.                 case IDM_COMPACT:
  518.                     if (wSize = GetSize("ShrinkHeap")) {
  519.                         MultLocalCompact(ActiveHeap, (wSize * 1024));
  520.                         RePaintChild();
  521.                     }
  522.                     break;
  523.  
  524.                 case IDM_DISCARD:
  525.                     if (hlMem = GetHandle()) {
  526.                         MultLocalDiscard(ActiveHeap, hlMem);
  527.                         RePaintChild();
  528.                     }
  529.                     break;
  530.  
  531.                 case IDM_FREE:
  532.                     if (hlMem = GetHandle()) {
  533.                         if ((MultLocalFlags(ActiveHeap, hlMem) & LMEM_LOCKCOUNT) == 0) {
  534.                             if (lpArena = LockArena()) {
  535.                                 for (i=1;i<=ARENALIMIT;i++) {
  536.                                     if (lpArena->handle == hlMem) {
  537.                                         lpArena->handle = MultLocalFree(ActiveHeap, hlMem);
  538.                                         RePaintChild();
  539.                                         break;
  540.                                     }
  541.                                     lpArena++;
  542.                                 }
  543.                                 UnlockArena();
  544.                             }
  545.                         }
  546.                         else
  547.                             MessageBox(hwnd,"Cannot Free Locked Objects", "Error", MB_ICONEXCLAMATION);
  548.                     }
  549.                     break;
  550.  
  551.                 case IDM_LOCK:
  552.                     if (hlMem = GetHandle()) {
  553.                         MultLocalLock(ActiveHeap, hlMem);
  554.                         RePaintChild();
  555.                     }
  556.                     break;
  557.  
  558.                 case IDM_REALLOC:
  559.                     if (wSize = GetHandleAndSize()) {
  560.                         hlMem = wLFlags;
  561.                         if (lpArena = LockArena()) {
  562.                             for (i=1;i<=ARENALIMIT;i++) {
  563.                                 if (lpArena->handle == hlMem) {
  564.                                     MultLocalReAlloc(ActiveHeap, hlMem, wSize, lpArena->wFlags);
  565.                                     RePaintChild();
  566.                                     break;
  567.                                 }
  568.                                 lpArena++;
  569.                             }
  570.                             UnlockArena();
  571.                         }
  572.                     }
  573.                     break;
  574.  
  575.                 case IDM_SHRINK:
  576.                     if (wSize = GetSize("ShrinkHeap")) {
  577.                         MultLocalShrink(ActiveHeap, (wSize * 1024));
  578.                         RePaintChild();
  579.                     }
  580.                     break;
  581.  
  582.                 case IDM_UNLOCK:
  583.                     if (hlMem = GetHandle()) {
  584.                         MultLocalUnlock(ActiveHeap, hlMem);
  585.                         RePaintChild();
  586.                     }
  587.                     break;
  588.             }
  589.             break;
  590.  
  591.         case WM_DESTROY:
  592.             PostQuitMessage( 0 );
  593.             break;
  594.     }
  595.     return DefFrameProc( hwnd, hwndMDIClient, msg, wParam, lParam );
  596. }
  597.  
  598.  
  599. /*----------------------------------------------------------------------------
  600.   Create a document window of a given color on the MDI desktop.
  601.   Allocate the heap for this window and store the handle in
  602.   the window extra bytes.
  603.  
  604.   Also stores the handle to our pseudo arena and arena size in
  605.   window extra words. This is for this test app only and not a
  606.   a part of the heap management routines.
  607. ----------------------------------------------------------------------------*/
  608.  
  609. BOOL MLHTestCreate(int wSize)
  610. {
  611.     char szTitle[80];
  612.     HWND hWnd;
  613.     HANDLE hMem;
  614.     HANDLE hLMem;
  615.     MDICREATESTRUCT  mcs;
  616.  
  617.  
  618.     // Allocate and Initialize Heap
  619.     if (hMem = MultLocalInit(wSize)) {
  620.  
  621.         // Format the MDI Child Title
  622.         sprintf( szTitle, "%s %X", "Heap ID", hMem);
  623.  
  624.         mcs.szTitle    = szTitle;
  625.         mcs.szClass    = szChild;
  626.         mcs.hOwner     = hInst;
  627.         mcs.x = mcs.cx = CW_USEDEFAULT;
  628.         mcs.y = mcs.cy = CW_USEDEFAULT;
  629.         mcs.style      = CHILDSTYLE;
  630.  
  631.         if (hWnd = (HANDLE) SendMessage(hwndMDIClient,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs)) {
  632.  
  633.             // Store the handle to the heap in the winextra word
  634.             SetWindowWord(hWnd, WE_HEAP, hMem);
  635.  
  636.             // Allocate space for ARENALIMIT arena entries
  637.             if (hLMem = MultLocalAlloc(hMem, (LMEM_MOVEABLE | LMEM_ZEROINIT), (ARENALIMIT * sizeof(LOCALARENA))))
  638.                 // Store the arena handle in window extra word
  639.                 SetWindowWord(hWnd, WE_ARENA, hLMem);
  640.                 RePaintChild();
  641.             }
  642.  
  643.         else {                  // Failure, so we need to clean up
  644.             GlobalUnlock(hMem); // LocalInit calls GlobalLock
  645.             GlobalFree(hMem);   // Free the Heap
  646.             return(FALSE);
  647.         }
  648.         return(TRUE);
  649.     }
  650.     else
  651.         return(FALSE);
  652. }
  653.  
  654.  
  655. VOID WalkArena(HWND hwnd)
  656. {
  657.     char szText[80];
  658.     PAINTSTRUCT paint;
  659.     LPLOCALARENA lpArena;
  660.     INT i,y;
  661.     WORD wFlags,wCount,wBSize,wHSize;
  662.     HANDLE hOldFont;
  663.     HWND hwndOldActive = hwndActive;
  664.  
  665.     hwndActive = hwnd;
  666.     BeginPaint(hwnd, &paint);
  667.     hOldFont = SelectObject(paint.hdc,GetStockObject(OEM_FIXED_FONT));
  668.     SetBkColor(paint.hdc, GetSysColor(COLOR_APPWORKSPACE - 1));
  669.  
  670.     if (lpArena = LockArena()) {
  671.         wFlags  = MultLocalFlags(ActiveHeap, ActiveArena);
  672.         wCount = (wFlags & LMEM_LOCKCOUNT);
  673.         wHSize = MultLocalSize(ActiveHeap, ActiveArena);
  674.         strcpy(szText, szTitle);
  675.         y=0;
  676.         TextOut(paint.hdc, 0, y, szText, strlen(szText));
  677.         TextOut(paint.hdc, 0, ((++y) * yChar), szBar, strlen(szBar));
  678.  
  679.         sprintf(szText, szPrint, ActiveArena, LOWORD( (DWORD) lpArena), wHSize, wCount, "Arena Table");
  680.         TextOut(paint.hdc, 0, ((++y) * yChar), szText, strlen(szText));
  681.  
  682.         for (i=1;i<=ARENALIMIT;i++) {
  683.             if (lpArena->handle != 0) {
  684.  
  685.                 wFlags = MultLocalFlags(ActiveHeap, lpArena->handle);
  686.                 wCount = (wFlags & LMEM_LOCKCOUNT);
  687.                 wBSize = MultLocalSize(ActiveHeap, lpArena->handle);
  688.                 wHSize += wBSize;
  689.  
  690.                 lpArena->offset = LOWORD( (DWORD) MultLocalLock(ActiveHeap,lpArena->handle));
  691.                 MultLocalUnlock(ActiveHeap, lpArena->handle);
  692.                 if ((wFlags & LMEM_DISCARDED) == LMEM_DISCARDED)
  693.                     sprintf(szText, szPrint,lpArena->handle, lpArena->offset, wBSize, wCount, "Discarded  ");
  694.                 else if ((wFlags & LMEM_DISCARDABLE) == LMEM_DISCARDABLE)
  695.                     sprintf(szText, szPrint,lpArena->handle, lpArena->offset, wBSize, wCount, "Discardable");
  696.                 else if (lpArena->handle == lpArena->offset)
  697.                     sprintf(szText, szPrint,lpArena->handle, lpArena->offset, wBSize, wCount, "Fixed      ");
  698.                 else
  699.                     sprintf(szText, szPrint,lpArena->handle, lpArena->offset, wBSize, wCount, "           ");
  700.  
  701.                 TextOut(paint.hdc, 0, ((++y) * yChar), szText, strlen(szText));
  702.             }
  703.             lpArena++;
  704.         }
  705.         TextOut(paint.hdc, 0, ((++y) * yChar), szBar, strlen(szBar));
  706.         wBSize = GlobalSize(ActiveHeap);
  707.         sprintf(szText, szSum, wBSize, wHSize, (wBSize - wHSize));
  708.         TextOut(paint.hdc, 0, ((++y) * yChar), szText, strlen(szText));
  709.         UnlockArena();
  710.     }
  711.     SelectObject(paint.hdc,hOldFont);
  712.     EndPaint(hwnd, &paint);
  713.     hwndActive = hwndOldActive;
  714. }
  715.  
  716. /*----------------------------------------------------------------------------
  717.   MDIChildWndProc(hwndChild, msg, wParam, lParam ) : LONG;
  718.   Handle messages for our documents.
  719. ----------------------------------------------------------------------------*/
  720. LONG FAR PASCAL MDIChildWndProc(HWND hwndChild,unsigned msg, WORD wParam, LONG lParam)
  721. {
  722.     HANDLE hlTemp, hMem;
  723.     LPLOCALARENA lpArena;
  724.  
  725.     switch (msg) {
  726.  
  727.         case WM_CREATE:
  728.             {
  729.                 HANDLE oldFont;
  730.                 TEXTMETRIC tm;
  731.                 LPCREATESTRUCT lpCS = (LPCREATESTRUCT) lParam;
  732.                 HDC hdc = GetDC(hwndChild);
  733.                 oldFont = SelectObject(hdc,GetStockObject(OEM_FIXED_FONT));
  734.                 lpCS->cx = LOWORD(GetTextExtent(hdc, szBar, strlen(szBar))) +
  735.                   (2 * GetSystemMetrics(SM_CXFRAME));
  736.                 SelectObject(hdc,oldFont);
  737.                 GetTextMetrics(hdc, &tm);
  738.                 xChar = tm.tmAveCharWidth;
  739.                 yChar = tm.tmHeight + tm.tmExternalLeading;
  740.                 ReleaseDC(hwndChild, hdc);
  741.                 MoveWindow(hwndChild, lpCS->x, lpCS->y, lpCS->cx, lpCS->cy, FALSE);
  742.             }
  743.             break;
  744.  
  745.         case WM_MDIACTIVATE:
  746.             if (wParam)
  747.                  hwndActive = hwndChild;
  748.             else
  749.                  hwndActive = NULL;
  750.             PostMessage(hwndFrame, WM_COMMAND, IDM_MENUCHANGE, 0L);
  751.             break;
  752.  
  753.         case WM_SIZE:
  754.             switch (wParam) {
  755.                 case SIZEICONIC:
  756.                 case SIZENORMAL:
  757.                 PostMessage(hwndFrame, WM_COMMAND, IDM_MENUCHANGE, 0L);
  758.                 break;
  759.             }
  760.             break;
  761.  
  762.         case WM_PAINT:
  763.             WalkArena(hwndChild);
  764.             break;
  765.  
  766.         case WM_DESTROY:
  767.             hMem = GetWindowWord(hwndChild, WE_HEAP);
  768.             GlobalUnlock(hMem);
  769.             if (GlobalFree(hMem))
  770.                 MessageBox(hwndFrame,"Cannot Free Heap", "Error", MB_ICONEXCLAMATION);
  771.             break;
  772.     }
  773.     return DefMDIChildProc(hwndChild, msg, wParam, lParam );
  774. }
  775.  
  776.  
  777. /*----------------------------------------------------------------------------
  778.   MainDlgAbout( hDlg, message, wParam, lParam ) : INT
  779.   Handle the ABOUT dialog box.
  780. ----------------------------------------------------------------------------*/
  781. INT FAR PASCAL MainDlgAbout(HWND hDlg,unsigned msg, WORD wParam, LONG lParam)
  782. {
  783.     int         iReturn = FALSE;  /* Return value */
  784.     switch(msg) {
  785.         case WM_INITDIALOG:
  786.             iReturn = TRUE;
  787.             break;
  788.  
  789.         case WM_COMMAND:
  790.             EndDialog(hDlg, TRUE);
  791.             break;
  792.     }
  793.     return iReturn;
  794. }
  795.  
  796. /*----------------------------------------------------------------------------
  797.   CloseAllChildren () : VOID
  798.   Destroys all MDI child windows
  799. ----------------------------------------------------------------------------*/
  800. VOID PASCAL CloseAllChildren ()
  801. {
  802.     register HWND hwnd;
  803.     ShowWindow(hwndMDIClient,SW_HIDE);
  804.     while (hwnd = GetWindow (hwndMDIClient, GW_CHILD)) {
  805.         while (hwnd && GetWindow (hwnd, GW_OWNER))
  806.             hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  807.  
  808.         if (!hwnd)
  809.             break;
  810.  
  811.         SendMessage (hwndMDIClient, WM_MDIDESTROY, (WORD)hwnd, 0L);
  812.     }
  813. }
  814.  
  815.  
  816. /*----------------------------------------------------------------------------
  817.   ReAllocDlgAbout( hDlg, message, wParam, lParam ) : INT
  818.   Handles messages for the ReAlloc dialog box.
  819. ----------------------------------------------------------------------------*/
  820. WORD FAR PASCAL ReAllocDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  821. {
  822.     int iReturn = FALSE;
  823.     switch(msg) {
  824.  
  825.         case WM_INITDIALOG:
  826.             SetDlgItemInt(hDlg, ID_BYTES, 1024, FALSE);
  827.             iReturn = TRUE;
  828.             break;
  829.  
  830.         case WM_COMMAND:
  831.             switch (wParam) {
  832.                 case IDOK:
  833.                     EndDialog(hDlg, GetDlgItemInt(hDlg, ID_BYTES, NULL, FALSE));
  834.                     wLFlags = GetDlgItemInt(hDlg, ID_HANDLE, NULL, FALSE);
  835.                     break;
  836.  
  837.                 case IDCANCEL:
  838.                     EndDialog(hDlg, 0);
  839.                     break;
  840.              }
  841.              break;
  842.     }
  843.     return iReturn;
  844. }
  845.  
  846. /*----------------------------------------------------------------------------
  847.   HandleDlgAbout( hDlg, message, wParam, lParam ) : INT
  848.   Handles messages for the Handle dialog box.
  849. ----------------------------------------------------------------------------*/
  850. HANDLE FAR PASCAL HandleDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  851. {
  852.     int iReturn = FALSE;
  853.     switch(msg) {
  854.  
  855.         case WM_INITDIALOG:
  856.             iReturn = TRUE;
  857.             break;
  858.  
  859.         case WM_COMMAND:
  860.             switch (wParam) {
  861.  
  862.                 case IDOK:
  863.                     EndDialog(hDlg, GetDlgItemInt(hDlg, ID_HANDLE, NULL, FALSE));
  864.                     break;
  865.  
  866.                 case IDCANCEL:
  867.                     EndDialog(hDlg, 0);
  868.                     break;
  869.             }
  870.             break;
  871.     }
  872.     return iReturn;
  873. }
  874.  
  875.  
  876. /*----------------------------------------------------------------------------
  877.   NewHeapDlgAbout( hDlg, message, wParam, lParam ) : INT
  878.   Handles messages for the NewHeap dialog box.
  879. ----------------------------------------------------------------------------*/
  880. INT FAR PASCAL NewHeapDlgProc(HWND hDlg,unsigned msg,WORD wParam, LONG lParam)
  881. {
  882.     int iReturn = FALSE;
  883.  
  884.     switch(msg) {
  885.  
  886.         case WM_INITDIALOG:
  887.             SetDlgItemInt(hDlg, ID_BYTES, 4, FALSE);
  888.             iReturn = TRUE;
  889.             break;
  890.  
  891.         case WM_COMMAND:
  892.             switch (wParam) {
  893.                 case IDOK:
  894.                     EndDialog(hDlg, GetDlgItemInt(hDlg, ID_BYTES, NULL, FALSE));
  895.                     break;
  896.                 case IDCANCEL:
  897.                     EndDialog(hDlg, 0);
  898.                     break;
  899.             }
  900.             break;
  901.     }
  902.     return iReturn;
  903. }
  904.  
  905. #define GetButtonValue(id,value) (IsDlgButtonChecked(hDlg,id)?value:0)
  906. #define SetButton(id,value) CheckDlgButton(hDlg,id,value)
  907. #define ToggleButton(id) CheckDlgButton(hDlg,id,(IsDlgButtonChecked(hDlg,id)?FALSE:TRUE))
  908.  
  909. /*----------------------------------------------------------------------------
  910.   AllocDlgProc( hDlg, message, wParam, lParam ) : INT
  911.   Handles messages for the Alloc dialog box.
  912. ----------------------------------------------------------------------------*/
  913. WORD FAR PASCAL AllocDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  914. {
  915.     int iReturn = FALSE;
  916.     switch(msg) {
  917.     
  918.         case WM_INITDIALOG:
  919.             SetDlgItemInt(hDlg, ID_ABYTES, 1024, FALSE);
  920.             SetButton(ID_DISC, FALSE);
  921.             SetButton(ID_FIXED, FALSE);
  922.             SetButton(ID_MOVES, TRUE);
  923.             SetButton(ID_NOCOMP, TRUE);
  924.             SetButton(ID_NODISC, TRUE);
  925.             SetButton(ID_ZERO, TRUE);
  926.             iReturn = TRUE;
  927.             break;
  928.  
  929.         case WM_COMMAND:
  930.             switch (wParam) {
  931.  
  932.                 case ID_FIXED:
  933.                     SetButton(ID_MOVES, FALSE);
  934.                     SetButton(ID_DISC, FALSE);
  935.                     SetButton(wParam, TRUE);
  936.                     break;
  937.  
  938.                 case ID_MOVES:
  939.                     SetButton(ID_FIXED, FALSE);
  940.                     SetButton(wParam, TRUE);
  941.                     break;
  942.  
  943.                 case ID_DISC:
  944.                     if (!IsDlgButtonChecked(hDlg, ID_FIXED))
  945.                         ToggleButton(wParam);
  946.                     break;
  947.  
  948.                 case ID_NOCOMP:
  949.                 case ID_NODISC:
  950.                 case ID_ZERO:
  951.                     ToggleButton(wParam);
  952.                     break;
  953.  
  954.                 case IDOK:
  955.                     wLFlags =  GetButtonValue(ID_DISC, LMEM_DISCARDABLE);
  956.                     wLFlags |= GetButtonValue(ID_FIXED, LMEM_FIXED);
  957.                     wLFlags |= GetButtonValue(ID_MOVES, LMEM_MOVEABLE);
  958.                     wLFlags |= GetButtonValue(ID_NOCOMP, LMEM_NOCOMPACT);
  959.                     wLFlags |= GetButtonValue(ID_NODISC, LMEM_NODISCARD);
  960.                     wLFlags |= GetButtonValue(ID_ZERO, LMEM_ZEROINIT);
  961.                     EndDialog(hDlg, GetDlgItemInt(hDlg, ID_ABYTES, NULL, FALSE));
  962.                     break;
  963.  
  964.                 case IDCANCEL:
  965.                     wLFlags = 0;
  966.                     EndDialog(hDlg, 0);
  967.                     break;
  968.             }
  969.             break;
  970.     }
  971.     return iReturn;
  972. }
  973.